//**********************************************************************
//	Programmer	-	Sujal Bista
//	File Name	-	model.cpp
//	Description	:	
//					3d model handler
//
//**********************************************************************
#include "model.h"

#ifdef _MSC_VER
	#ifdef _DEBUG
		#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
		#define new DEBUG_NEW
	#else
		#define DEBUG_NEW new
	#endif
#endif

//constructor
model::model(void)
{
	staticMeshHeader.meshCount=0;
	staticMeshHeader.animationCount=0;
	staticMeshHeader.skinCount=0;
	
	staticMeshHeader.meshes=NULL;
	staticMeshHeader.animations=NULL;
	staticMeshHeader.skins=NULL;
	
}

//init
bool model::init(graphicsUtility &glu)
{
	graphicsDefinitions::TEXTURE_ADDRESS_MODE addMode[3]=
		{
			graphicsDefinitions::TEXTURE_ADDRESS_MODE_CLAMP,
			graphicsDefinitions::TEXTURE_ADDRESS_MODE_CLAMP,
			graphicsDefinitions::TEXTURE_ADDRESS_MODE_CLAMP
		};
	float borderColor[4]={0,0,0,0};
	//get device
	device &graphicsDevice=glu.getDevice();

	for(unsigned int i=0;i<staticMeshHeader.meshCount;i++)
	{
		mesh &currMesh=staticMeshHeader.meshes[i];
		for(unsigned int j=0;j<currMesh.materialCount;j++)
		{
			mesh::material &currMaterial=currMesh.materials[j];
			
			if(currMaterial.textureSRV || currMaterial.textureSampler)
				continue;

			currMaterial.textureSRV= new shaderResourceView;
			currMaterial.textureSampler= new samplerState;

			//create the texture
			if(!graphicsDevice.createShaderResourceViewFromFile(currMaterial.fileName,(currMaterial.textureSRV)))
				return false;
					
			//create the sampler
			if(!graphicsDevice.createSamplerState(
					graphicsDefinitions::FILTER_MIN_MAG_MIP_LINEAR,
					addMode,
					0,
					0,
					graphicsDefinitions::COMPARISON_FUNC_NEVER,
					borderColor,
					0,
					10000,
					currMaterial.textureSampler
				))
				return false;
		}
	}

	return true;
}

//updates the mesh
void model::update(const float &dt)
{
	//update all the instances
	for(unsigned int i=0;i<instances.size();i++)
	{		
		instance &currInstance=instances[i];

		//update the instance
		currInstance.update(dt);
	}
}

//show the mesh
void model::show(graphicsUtility &glu,const camera &eye,const bool useTexture)
{
	//update all the instances
	for(unsigned int i=0;i<instances.size();i++)
	{		
		instance &currInstance=instances[i];

		//shows an instance
		currInstance.show(glu,eye,useTexture);
	}
}

//free the data
void model::clear(void)
{
	delete[] staticMeshHeader.meshes;
	staticMeshHeader.meshes=NULL;

	delete[] staticMeshHeader.animations;
	staticMeshHeader.animations=NULL;

	delete[] staticMeshHeader.skins;
	staticMeshHeader.skins=NULL;
	
	staticMeshHeader.animationCount=0;
	staticMeshHeader.meshCount=0;
	staticMeshHeader.skinCount=0;
}

//destructor
model::~model()
{
	//free the data
	clear();
}

//get total number of active faces
//includes all the instances
unsigned int model::getActiveFacesSize(void)
{
	unsigned int totalFaces=0;
	//update all the instances
	for(unsigned int i=0;i<instances.size();i++)
	{		
		instance &currInstance=instances[i];

		//add number of faces
		totalFaces+=currInstance.meshPtr->faceCount;
	}

	return totalFaces;

}

//write the file
bool model::write(char *fileName)
{
	modelQuick meshQ;
	//copy the data
	meshQ=*this;
	////save the file
	return meshQ.write(fileName);
}

